有一個東西不受資料型別的限制,還能讓同一個函式收到不同型別傳來的值。
他是誰?

Interface 是一個定義一組方法的命名型態,任何類型只要實現了這些方法,就被視為實現了該 Interface 。這使得不同的類型可以用相同的方式進行操作。
假設你在一個火車站,有不同種類的火車(不同類型的對象)像是自強號、莒光號、...要進站(被用在某個程式碼中)。
火車站有統一的 月台 ,我們將月台想像成 Interface,每種火車都需要停在這個月台上,並且必須具備某些基本特徵,例如:能夠開車、停車、回報目的與狀況...等。這個月台定義了所有火車 共享 的操作,但不關心具體火車的型號。
舉例:
package main
import "fmt"
// 定義一個月台 (interface)
type TrainPlatform interface {
    StartRunning()
    StopRunning()
    ReportDestination(string)
}
// 定義區間車的結構
type RegularTrain struct {
    Name string
}
// 
func (t RegularTrain) StartRunning() {
    fmt.Printf("%s 開車!\n", t.Name)
}
// 
func (t RegularTrain) StopRunning() {
    fmt.Printf("%s 停車 !\n", t.Name)
}
// 報告目的
func (t RegularTrain) ReportDestination(destination string) {
    fmt.Printf("%s 即將到站 %s!\n", t.Name, destination)
}
func main() {
    trainA := RegularTrain{Name: "區間特快"}
    trainA.StartRunning()
    trainA.ReportDestination("彰化")
    trainA.StopRunning()
}
區間特快 開車!
區間特快 即將到站 彰化!
區間特快 停車 !
有一個溫度,以攝氏度表示,但你需要將其轉換為華氏度。這是一個常見的數據轉換。攝氏度到華氏度的轉換公式如下:
華氏度 = (攝氏度 × 9/5) + 32
package main
import "fmt"
func main() {
	celsius := 25.0                      // 攝氏度
	fahrenheit := (celsius * 9 / 5) + 32 // 轉換為華氏度
	fmt.Printf("攝氏 %.2f 度 = 華氏 %.2f 度\n", celsius, fahrenheit)
}
攝氏 25.00 度 = 華氏 77.00 度
Interface Conversions 將一個實現了某介面的具體類型轉換為該介面的操作。
舉例:
有一台電腦主機,主機有多個 USB 接口可以接受 不同種類 的USB 設備,例如 USB 滑鼠、USB 鍵盤、USB 影印機...等等。
這裡的USB接口就可以被視為一個 interface ,它定義了一組標準方法(例如數據傳輸、電源供應等等),這些方法可以被不同種類的 USB 設備連接。
舉例:
package main
import "fmt"
// 定義 USB 設備 interface
type USBDevice interface {
	Connect()
	Disconnect()
}
// 定義 USB 滑鼠
type USBMouse struct {
	Name string
}
func (m USBMouse) Connect() {
	fmt.Printf("%s 滑鼠已連線。\n", m.Name)
}
func (m USBMouse) Disconnect() {
	fmt.Printf("%s 滑鼠離開連線\n", m.Name)
}
// 定義 USB 鍵盤
type USBKeyboard struct {
	Name string
}
func (k USBKeyboard) Connect() {
	fmt.Printf("%s 鍵盤已連線\n", k.Name)
}
func (k USBKeyboard) Disconnect() {
	fmt.Printf("%s 鍵盤離開連線\n", k.Name)
}
func main() {
	mouse := USBMouse{Name: "Logitech"}
	keyboard := USBKeyboard{Name: "Dell"}
	devices := []USBDevice{mouse, keyboard}
	for _, device := range devices {
		device.Connect()
		device.Disconnect()
	}
}
Logitech 滑鼠已連線。
Logitech 滑鼠離開連線
Dell 鍵盤已連線
Dell 鍵盤離開連線
Type Assertions 用於檢查介面值的 實際存儲類型 ,並將其轉換為該具體類型。
package main
import "fmt"
// 定義一個介面叫做Shape
type Shape interface {
    Area() float64
}
// 定義一個矩形結構
type Rectangle struct {
    Width  float64
    Height float64
}
// 實現Shape介面的Area方法
func (r Rectangle) Area() float64 {
    return r.Width * r.Height
}
func main() {
    rectangle := Rectangle{Width: 5, Height: 3}
    // 將Rectangle實例轉換為Shape介面
    var shape Shape
    shape = rectangle
    // 使用 Type Assertions 檢查介面值的實際類型並取得具體類型的值
    if r, ok := shape.(Rectangle); ok {
        fmt.Printf("矩形的寬度:%f\n", r.Width)
    } else {
        fmt.Println("這不是一個矩形。")
    }
}
矩形的寬度:5.000000
Generality 指的是 Interface 提供的方式用来描述對象的行為,而不考慮型別。這允許不同型別的對應相同的 Interface ,可以用一致的方式進行操作和處理。
舉例:
package main
import "fmt"
// 定義一個通用的 Shape interface
type Shape interface {
	Area() float64
}
// 定義一個矩形結構體
type Rectangle struct {
	Width  float64
	Height float64
}
func (r Rectangle) Area() float64 {
	return r.Width * r.Height
}
type Circle struct {
	Radius float64
}
func (c Circle) Area() float64 {
	return 3.14 * c.Radius * c.Radius
}
func main() {
	rectangle := Rectangle{Width: 5, Height: 3}
	circle := Circle{Radius: 2}
	// 使用通用的 Shape interface 来計算面積
	shapes := []Shape{rectangle, circle}
	for _, shape := range shapes {
		area := shape.Area()
		fmt.Printf("面積:%f\n", area)
	}
}
面積:15.000000
面積:12.560000
Interface 為我們提供了一種通用的方式來描述不同對象的行為,就像 Platform 9¾ 為麻瓜們提供了通往霍格華茲的道路一樣。
(都入秋了為什麼還這麼熱!